/*
 * Filename:    AuditReviewResultSurveyServiceImpl.java
 * Copyright:   2014 中国平安保险（集团）股份有限公司 版权所有
 * Company:     平安科技养老险及健康险系统开发部
 * Create at:   2014-11-13
 */
package com.paic.mhis.hcpms.audit.biz.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSONObject;
import com.paic.mhis.core.auth.biz.service.Authority;
import com.paic.mhis.core.auth.biz.service.UserDetails;
import com.paic.mhis.hcpms.audit.biz.service.AuditProblemsService;
import com.paic.mhis.hcpms.audit.biz.service.AuditService;
import com.paic.mhis.hcpms.audit.biz.service.AuditWorkFlowService;
import com.paic.mhis.hcpms.audit.biz.service.IAuditReviewResultSurvey;
import com.paic.mhis.hcpms.audit.biz.service.ICaseCommonService;
import com.paic.mhis.hcpms.audit.biz.service.RandomCodeService;
import com.paic.mhis.hcpms.audit.constants.AuditConstants;
import com.paic.mhis.hcpms.audit.dao.AuditDispatchDao;
import com.paic.mhis.hcpms.audit.dao.AuditOpinionDao;
import com.paic.mhis.hcpms.audit.dao.AuditSurveyReviewDao;
import com.paic.mhis.hcpms.audit.dao.CaseCommonDao;
import com.paic.mhis.hcpms.audit.dto.AuditDispatchUserRequestDTO;
import com.paic.mhis.hcpms.audit.dto.AuditDispatchUserResponseDTO;
import com.paic.mhis.hcpms.audit.dto.AuditOpinionDTO;
import com.paic.mhis.hcpms.audit.dto.AuditPointCutTempDTO;
import com.paic.mhis.hcpms.audit.dto.AuditProblemsDTO;
import com.paic.mhis.hcpms.audit.dto.AuditTargetDTO;
import com.paic.mhis.hcpms.audit.dto.AuditiCaseDTO;
import com.paic.mhis.hcpms.audit.util.EventCodeUtil;
import com.paic.mhis.hcpms.audit.util.GetFormDateUtil;
import com.paic.mhis.hcpms.common.storage.biz.service.HcpmsStorageService;
import com.paic.mhis.hcpms.common.storage.dto.HcpmsStorageDTO;
import com.paic.mhis.hcpms.common.workflow.vo.HcpmsWorkFlowVO;
import com.paic.mhis.hcpms.trust.biz.service.IntegrityMedicalService;
import com.paic.mhis.hcpms.warning.biz.service.WarningFromAuditService;
import com.paic.mock.util.StringUtils;

@Component("auditReviewResultSurveyServiceImpl")
public class AuditReviewResultSurveyServiceImpl implements
		IAuditReviewResultSurvey {

	@Autowired
	private AuditDispatchDao auditDispatchDao;

	@Autowired
	private AuditOpinionDao auditOpinionDao;

	@Autowired
	private AuditSurveyReviewDao auditSurveyReviewDao;

	@Autowired
	private AuditProblemsService auditProblemsService;

	@Autowired
	private IntegrityMedicalService integrityMedicalService;

	@Autowired
	private CaseCommonDao caseCommonDao;

	@Autowired
	private RandomCodeService randomCodeService;

	@Autowired
	private AuditService auditService;

	@Resource(name = "warningFromAuditService")
	private WarningFromAuditService warningFromAuditService;

	public static final String CASETYPE = "JH";

	public static final String PROBLEMTYPE = "SJ";

	private static final String type_save = "save";

	private static final String type_load = "load";

	@Autowired
	private AuditWorkFlowService auditWorkFlowService; // 流程服务

	@Autowired
	private HcpmsStorageService hcpmsStorageService; // 暂存处理

	@Autowired
	private ICaseCommonService caseCommonService;

	/**
	 * 审核岗位 审核调查结果 通过选择人员进行稽核 分配任务 1.A岗位 需要稽核 B岗位同意 C岗位同意 分配人员做稽核
	 * 
	 * 2.A岗位 需要稽核 B岗位同意 C岗位重新调查 分配人员做调查 3.A岗位 需要稽核 B岗位保留意见 C岗位重新调查 分配人员做调查 4.A岗位
	 * 不需要稽核 B岗位同意 C岗位重新调查 分配人员做调查 5.A岗位 不需要稽核 B岗位保留意见 C岗位重新调查 分配人员做调查
	 * 
	 * @param vo
	 * @throws Exception
	 */
	@Transactional
	public void auditSurveyResultTask(AuditDispatchUserRequestDTO requestBean,
			UserDetails user, JSONObject transferJson) throws Exception {

		integrityMedicalService.addIntegrityPointTemps(transferJson,
				user.getUsername());// 临时扣分
		// 删除暂存表临时保存的数据
		HcpmsStorageDTO tempObject = this.setTempObject(requestBean,
				user.getUsername(), AuditConstants.opinionType_5,
				AuditConstants.examine, AuditConstants.sjModule);
		this.hcpmsStorageService.deleteStorageData(tempObject);
		this.caseCommonService.deleteAuditCasePoint(requestBean.getProblemNo(),
				user.getUsername());

		/*
		 * String auserOpinion = requestBean.getSurveyOpinion(); // A岗位意见 String
		 * buserOpinion = requestBean.getReviewResult(); // B岗位意见
		 */
		String cuserOpinion = requestBean.getOpinion(); // C 岗位意见

		this.updateOpinionInfo(requestBean.getSurveyOpinonDesc(),
				requestBean.getReviewOpinionDesc(), requestBean.getProblemNo());

		/*
		 * if (auserOpinion.equals(AuditConstants.opinionResult_1) &&
		 * buserOpinion.equals(AuditConstants.opinionResult_1) &&
		 * cuserOpinion.equals(AuditConstants.opinionResult_1)) {
		 * this.processAuditTask(requestBean, user);// 稽核 } else {
		 * this.processRepeatDispatchSurvey(requestBean);// 重新调查 }
		 */

		if (AuditConstants.opinionResult_1.equals(cuserOpinion)) {
			this.processAuditTask(requestBean, user);// 稽核
		} else if (AuditConstants.opinionResult_0.equals(cuserOpinion)) {
			this.processRepeatDispatchSurvey(requestBean);// 重新调查
		}

	}

	/**
	 * @param requestBean
	 *            请求参数
	 * @param user
	 *            用户信息
	 * @param businessType
	 *            意见类型
	 * @param childModuleType
	 *            子模块类型
	 * @param moduleType
	 *            模块类型
	 * @return
	 */
	private HcpmsStorageDTO setTempObject(
			AuditDispatchUserRequestDTO requestBean, String userName,
			String businessType, String childModuleType, String moduleType) {
		HcpmsStorageDTO tempObject = new HcpmsStorageDTO();
		tempObject.setBusinessId(requestBean.getProblemNo());
		tempObject.setModuleType(moduleType);
		tempObject.setChildModuleType(childModuleType);
		tempObject.setBusinessType(businessType);
		tempObject.setUserId(userName);
		tempObject.setDataMap(requestBean);
		return tempObject;
	}

	/**
	 * 分配人员做稽核 1.根据事件编号加载当前事件对象，然后将该对象的部分信息拷贝到案件对象中，然后保存案件对象到案件表中状态为待稽核
	 * 2.结束当前的事件状态，根据事件编码加载事件的稽核对象，将部分信息拷贝出来，然后在生成一条案件稽核对象 3.生成事件意见.4生成稽核意见
	 * 结束事件流程 ,新开起案件流程
	 * 
	 * @param requestBean
	 * @throws Exception
	 */
	@Transactional
	private void processAuditTask(AuditDispatchUserRequestDTO requestBean,
			UserDetails user) throws Exception {

		Date date = new Date();
		String dateStr = GetFormDateUtil.getStrFromDate(date);

		String problemNo = requestBean.getProblemNo();
		AuditProblemsDTO paramter = new AuditProblemsDTO();
		paramter.setProblemCode(problemNo);
		AuditProblemsDTO problemBean = this.auditSurveyReviewDao
				.queryAuditProblemsDTO(paramter);

		AuditiCaseDTO caseBean = new AuditiCaseDTO();
		caseBean.setCreatedBy(requestBean.getOpertionUsername());
		caseBean.setUpdatedBy(requestBean.getOpertionUsername());
		this.getAuditiCaseDTO(problemBean, caseBean);
		// 保存案件对象
		this.auditSurveyReviewDao.saveAuditCaseDTO(caseBean);

		// 更新事件状态为结束
		AuditProblemsDTO bean = new AuditProblemsDTO();
		bean.setProblemCode(problemNo);
		bean.setProblemStatus(AuditConstants.problemStatus_7);
		bean.setCaseCode(caseBean.getCaseCode());
		bean.setUpdatedBy(requestBean.getOpertionUsername());
		bean.setTempFlag(AuditConstants.TEMP_FLAG_0);
		this.auditDispatchDao.updateAuditProblemBean(bean);

		// 拷贝稽核对象
		AuditTargetDTO targetDto = new AuditTargetDTO();
		targetDto.setTaskCode(problemNo);
		targetDto.setTaskType(AuditConstants.taskType_01);

		List<AuditTargetDTO> queryBeanList = this.auditSurveyReviewDao
				.queryAuditTargetDTO(targetDto);

		if (queryBeanList != null && queryBeanList.size() > 0) {
			for (AuditTargetDTO queryBean : queryBeanList) {
				AuditTargetDTO reviewTargetBean = new AuditTargetDTO();
				reviewTargetBean
						.setCreatedBy(requestBean.getOpertionUsername());
				reviewTargetBean.setIsDeleted(AuditConstants.isDeleted);
				reviewTargetBean.setTargetCode(queryBean.getTargetCode());
				reviewTargetBean.setTaskType(AuditConstants.taskType_02);
				reviewTargetBean.setTaskCode(caseBean.getCaseCode());
				reviewTargetBean.setTargetType(queryBean.getTargetType());
				this.auditSurveyReviewDao
						.insertAuditTargetDTO(reviewTargetBean);

			}
		}

		// 生成事件意见
		AuditOpinionDTO problemOpinion = new AuditOpinionDTO();
		problemOpinion.setProblemNo(problemNo);
		problemOpinion.setTaskType(AuditConstants.taskType_01);
		problemOpinion.setOpinion(requestBean.getOpinion());
		problemOpinion.setOpinionDesc(requestBean.getOpinionDesc());
		problemOpinion.setOpinionType(AuditConstants.opinionType_5);
		problemOpinion.setDealDate(dateStr);
		problemOpinion.setDealUserName(requestBean.getOpertionUsername());
		problemOpinion.setCreatedBy(requestBean.getOpertionUsername());

		this.processOpinionInfo(problemOpinion);

		// 生成案件意见
		AuditOpinionDTO auditOpinion = new AuditOpinionDTO();
		auditOpinion.setProblemNo(caseBean.getCaseCode());
		auditOpinion.setTaskType(AuditConstants.taskType_02);
		auditOpinion.setAppointFirst(requestBean.getUserCode());
		auditOpinion.setAppointSecond(requestBean.getUserBCode());
		auditOpinion.setOpinionType(AuditConstants.opinionType_10);
		auditOpinion.setDealDate(dateStr);
		auditOpinion.setIsDeleted(AuditConstants.isDeleted);
		auditOpinion.setDealUserName(requestBean.getOpertionUsername());
		auditOpinion.setCreatedBy(requestBean.getOpertionUsername());

		this.processOpinionInfo(auditOpinion);

		// /拷贝积分信息
		AuditPointCutTempDTO point = new AuditPointCutTempDTO();
		point.setCaseType(AuditConstants.case_type_02);
		point.setCaseNo(problemNo);
		List<AuditPointCutTempDTO> pointList = this.caseCommonDao
				.loadAuditPointCutTempDTO(point);

		if (pointList != null && pointList.size() > 0) {
			for (AuditPointCutTempDTO currentPoint : pointList) {

				AuditPointCutTempDTO newPointBean = new AuditPointCutTempDTO();
				BeanUtils.copyProperties(currentPoint, newPointBean);
				newPointBean.setCaseNo(caseBean.getCaseCode());
				this.caseCommonDao.saveAuditPointCutTempDTO(newPointBean);
			}
		}

		// 结束事件当前流程
		Map<String, String> condition = new HashMap<String, String>();
		condition.put(AuditConstants.AUDIT_PROBLEM_CHECK_TYPE,
				AuditConstants.AUDIT_PROBLEM_CHECK_TYPE_01);
		this.auditWorkFlowService.processWorkFlow(problemNo, user, condition,
				AuditConstants.TASK_TYPE_PROBLEM);

		// 开起案件流程
		HcpmsWorkFlowVO wfvo = new HcpmsWorkFlowVO();
		wfvo.setTaskNo(caseBean.getCaseCode());
		wfvo.setTaskType(AuditConstants.TASK_TYPE_CASE);
		wfvo.setActCurrent(user.getUsername().toUpperCase());
		wfvo.setAssigner(requestBean.getUserCode().toUpperCase());
		this.auditWorkFlowService.startWorkFlow(wfvo);

	}

	/**
	 * 将事件对象的某些属性拷贝到案件对象中去
	 * 
	 * @param bean
	 * @param caseBean
	 * @return
	 */
	private void getAuditiCaseDTO(AuditProblemsDTO bean, AuditiCaseDTO caseBean) {

		// String caseCode =
		// this.auditProblemsService.querySeqTaskNoByBizType(CASETYPE);
		// 获取案件稽核编号
		String caseCode = this.randomCodeService.getCode(
				EventCodeUtil.event_codeJH, EventCodeUtil.industry_type2);
		if (org.apache.commons.lang.StringUtils.isEmpty(caseCode)) {
			caseCode = this.randomCodeService.getCode(
					EventCodeUtil.event_codeJH, EventCodeUtil.industry_type2);
		}
		caseBean.setCaseCode(caseCode);
		caseBean.setCaseStatus(AuditConstants.auditCaseStatus_2);
		caseBean.setRelatedCode(bean.getProblemCode());
		caseBean.setRelatedType(AuditConstants.relatedType_1);
		caseBean.setKeyPoint(bean.getKeyPoint());
		caseBean.setDetailDesc(bean.getDetailDesc());
		caseBean.setSourceType(bean.getSourceType());
		caseBean.setComplaintType(bean.getComplaintType());
		caseBean.setContactUsername(bean.getContactUsername());
		caseBean.setContactPhone(bean.getContactPhone());
		caseBean.setContactAddress(bean.getContactAddress());
		caseBean.setContactMail(bean.getContactMail());
		caseBean.setOtherCaseCode(bean.getOtherCaseCode());
		caseBean.setIsDeleted(AuditConstants.isDeleted);
		caseBean.setTargetType(bean.getTargetType());
		caseBean.setTempFlag(AuditConstants.TEMP_FLAG_0);
		caseBean.setRollbackFlag(AuditConstants.rollBackFlag_0);
		caseBean.setSourceTarget(bean.getSourceTarget());

	}

	/**
	 * 审核岗对事件调查结果的审核：重新调查逻辑处理 重新分配人员调查
	 * 
	 * 1.1保存当前人员的审核意见，但是要虚拟删除掉,然后将分配的人员更新到当前意见类型是事件审核的分配人员中
	 * 1.如果选择的重新调查人员A岗位和B岗位是之前的人员，则将当前的事件状态改成事件待调查，重新让他们调查和复核.
	 * 此时需要将流程扭转，之前的意见不变只是在重新调查录入意见的时候先查询，如果有则更新，没有则插入
	 * 2.如果选择的人员和之前的不一样，假设当前的事件号是A,则事件A状态改成已经结束且虚拟删除.
	 * 将A信息拷贝一份出来且状态扭转到事件待调查生成事件B,将A的稽核对象表(hcpms_audit_target)的信息拷贝出来给B,然后虚拟删除A.
	 * 将A信息的意见意见类型1.调查初审 2-事件审核3-调查结论4-调查结论复核 虚拟删除掉，同时将1.调查初审 2-事件审核 这个状态的意见拷贝给B
	 * 此时的B事件从新启动流程
	 * 
	 * 
	 * @param requestBean
	 * @throws Exception
	 */
	@Transactional
	private void processRepeatDispatchSurvey(
			AuditDispatchUserRequestDTO requestBean) throws Exception {

		String problemNo = requestBean.getProblemNo();
		// 保存当前的意见
		Date dealDate = new Date();
		String dealDateStr = GetFormDateUtil.getStrFromDate(dealDate);

		AuditOpinionDTO problemOpinion = new AuditOpinionDTO();
		problemOpinion.setProblemNo(problemNo);
		problemOpinion.setTaskType(AuditConstants.taskType_01);
		problemOpinion.setOpinion(requestBean.getOpinion());
		problemOpinion.setOpinionDesc(requestBean.getOpinionDesc());
		problemOpinion.setOpinionType(AuditConstants.opinionType_5);
		problemOpinion.setDealDate(dealDateStr);
		problemOpinion.setDealUserName(requestBean.getOpertionUsername());
		problemOpinion.setCreatedBy(requestBean.getOpertionUsername());

		// 根据当前的事件号去加载3-调查结论4-调查结论复核这两个意见类型
		AuditOpinionDTO parameter = new AuditOpinionDTO();
		parameter.setProblemNo(problemNo);
		parameter.setTaskType(AuditConstants.taskType_01);
		parameter.setOpinionType(AuditConstants.opinionType_3);

		AuditOpinionDTO surveyOpinonA = this.auditOpinionDao
				.getOpinionByType(parameter);

		parameter.setOpinionType(AuditConstants.opinionType_4);

		AuditOpinionDTO surveyOpinonB = this.auditOpinionDao
				.getOpinionByType(parameter);

		String dealAUsername = surveyOpinonA.getDealUserName();
		String dealBUsername = surveyOpinonB.getDealUserName();

		String userACode = requestBean.getUserCode();
		String userBCode = requestBean.getUserBCode();

		// 重新分配的A岗位的和B岗位的和之前的一样
		if (userACode.equals(dealAUsername) && userBCode.equals(dealBUsername)) {

			this.processDispatchSameInfo(requestBean, userACode, userBCode);
			// 处理审核意见
			List<AuditOpinionDTO> queryOpinionList = this.auditOpinionDao
					.queryAuditOpinionDTOInfo(problemOpinion);
			if (queryOpinionList != null && queryOpinionList.size() > 0) {

				AuditOpinionDTO updateOpinion = queryOpinionList.get(0);
				updateOpinion.setOpinion(requestBean.getOpinion());
				updateOpinion.setOpinionDesc(requestBean.getOpinionDesc());
				updateOpinion.setDealDate(dealDateStr);
				updateOpinion
						.setDealUserName(requestBean.getOpertionUsername());
				this.auditOpinionDao.updateAuditOpinionDTOInfo(updateOpinion);

			} else {
				problemOpinion.setIsDeleted(AuditConstants.isDeleted);
				this.auditOpinionDao.addOpinion(problemOpinion);
			}

		} else {

			String newProblemNo = this.processDispatchDifferentInfo(
					requestBean, dealAUsername, dealBUsername);
			// 处理审核意见
			List<AuditOpinionDTO> queryOpinionList = this.auditOpinionDao
					.queryAuditOpinionDTOInfo(problemOpinion);
			if (queryOpinionList != null && queryOpinionList.size() > 0) {
				problemOpinion.setIsDeleted(AuditConstants.isDeleted_1);
				this.auditOpinionDao.updateAuditOpinionDTOInfo(problemOpinion);

			} else {
				problemOpinion.setIsDeleted(AuditConstants.isDeleted_1);
				this.auditOpinionDao.addOpinion(problemOpinion);
			}

			if (userACode.equals(dealAUsername)
					|| userBCode.equals(dealBUsername)) {

				// 给新的事件新增审核结果处理
				problemOpinion.setIsDeleted(AuditConstants.isDeleted);
				problemOpinion.setProblemNo(newProblemNo);
				this.processOpinionInfo(problemOpinion);

			}

		}

	}

	/**
	 * 处理分配人员相同的情况 1.将当前的事件状态改成事件待调查,扭转流程
	 * 
	 * @param requestBean
	 * @throws Exception
	 */
	@Transactional
	private void processDispatchSameInfo(
			AuditDispatchUserRequestDTO requestBean, String userACode,
			String userBCode) throws Exception {
		String problemNo = requestBean.getProblemNo();
		AuditProblemsDTO bean = new AuditProblemsDTO();
		bean.setProblemCode(problemNo);
		bean.setProblemStatus(AuditConstants.problemStatus_4);
		bean.setRollbackFlag(AuditConstants.rollBackFlag_1);
		bean.setTempFlag(AuditConstants.TEMP_FLAG_0);
		this.auditDispatchDao.updateAuditProblemBean(bean);

		// 扭转流程
		UserDetails user = requestBean.getUser();
		Map<String, String> condition = new HashMap<String, String>();
		condition.put(AuditConstants.AUDIT_PROBLEM_CHECK_TYPE,
				AuditConstants.AUDIT_PROBLEM_CHECK_TYPE_02);

		this.auditWorkFlowService.processWorkFlow(problemNo, user, userACode,
				condition, AuditConstants.TASK_TYPE_PROBLEM);

	}

	/**
	 * 处理分配人员不相同的情况 返回新的事件号
	 * 
	 * @param requestBean
	 * @throws Exception
	 */
	@Transactional
	private String processDispatchDifferentInfo(
			AuditDispatchUserRequestDTO requestBean, String dealAUsername,
			String dealBUsername) throws Exception {
		String userACode = requestBean.getUserCode();
		String userBCode = requestBean.getUserBCode();
		String problemNo = requestBean.getProblemNo();
		UserDetails user = requestBean.getUser();

		// 根据事件号加载事件对象，进行拷贝后在删除事件
		AuditProblemsDTO problemParamter = new AuditProblemsDTO();
		problemParamter.setProblemCode(problemNo);
		AuditProblemsDTO problemQuery = this.auditSurveyReviewDao
				.queryAuditProblemsDTO(problemParamter);

		AuditProblemsDTO copyObject = new AuditProblemsDTO();
		BeanUtils.copyProperties(problemQuery, copyObject); // 拷贝属性
		// 重新生产事件编号
		String newProblemNo = this.randomCodeService.getCode(
				EventCodeUtil.event_codeSJ, EventCodeUtil.industry_type1);
		if (org.apache.commons.lang.StringUtils.isEmpty(newProblemNo)) {
			newProblemNo = randomCodeService.getCode(
					EventCodeUtil.event_codeSJ, EventCodeUtil.industry_type1);
		}
		copyObject.setProblemCode(newProblemNo);
		copyObject.setProblemStatus(AuditConstants.problemStatus_4);
		copyObject.setTempFlag(AuditConstants.opinionResult_0); // 不占存

		// 将当前的事件虚拟删除掉
		problemQuery.setIsDeleted(AuditConstants.isDeleted_1);
		problemQuery.setProblemStatus(AuditConstants.problemStatus_7);
		problemQuery.setRollbackFlag(AuditConstants.rollBackFlag_1);
		this.auditDispatchDao.updateAuditProblemBean(problemQuery);

		AuditPointCutTempDTO pointCondition = new AuditPointCutTempDTO();
		pointCondition.setCaseType(AuditConstants.case_type_02);
		pointCondition.setCaseNo(problemNo);
		pointCondition.setIsValid(AuditConstants.isDeleted);

		List<AuditPointCutTempDTO> pointList = this.caseCommonDao
				.loadAuditPointCutTempDTO(pointCondition);
		if (pointList != null && pointList.size() > 0) {
			for (AuditPointCutTempDTO currentBean : pointList) {

				AuditPointCutTempDTO newPointBean = new AuditPointCutTempDTO();

				BeanUtils.copyProperties(currentBean, newPointBean);
				newPointBean.setCaseNo(newProblemNo);
				newPointBean.setIsValid(AuditConstants.isDeleted);
				this.caseCommonDao.saveAuditPointCutTempDTO(newPointBean);

			}
		}

		// 根据事件号和任务类型加载对应的事件要稽核的对象
		AuditTargetDTO targetParamter = new AuditTargetDTO();
		targetParamter.setTaskCode(problemNo);
		targetParamter.setTaskType(AuditConstants.taskType_01);
		List<AuditTargetDTO> list = this.auditSurveyReviewDao
				.queryAuditTargetDTO(targetParamter);

		if (list != null && list.size() > 0) {
			for (AuditTargetDTO currentTarget : list) {

				AuditTargetDTO newTargetBean = new AuditTargetDTO();
				BeanUtils.copyProperties(currentTarget, newTargetBean);
				newTargetBean.setTaskCode(newProblemNo);

				// 保存新的稽核对象
				this.auditSurveyReviewDao.insertAuditTargetDTO(newTargetBean);

				// 将老的稽核对象虚拟删除掉
				currentTarget.setIsDeleted(AuditConstants.isDeleted_1);
				this.auditSurveyReviewDao.updateAuditTargetInfo(currentTarget);

			}
		}

		// 处理意见信息，将的当前事件的所有处理意见都加载出来.
		AuditOpinionDTO paramterOpinion = new AuditOpinionDTO();
		paramterOpinion.setProblemNo(problemNo);
		paramterOpinion.setTaskType(AuditConstants.taskType_01);
		// 加载调查初审和调查审核的意见,将该意见拷贝给新的事件意见中，并将其状态改成删除的
		paramterOpinion.setOpinionType("'" + AuditConstants.opinionType_1
				+ "','" + AuditConstants.opinionType_2 + "'");
		List<AuditOpinionDTO> opinionList = this.auditOpinionDao
				.queryAuditOpinionDTOInfo(paramterOpinion);

		if (opinionList != null && opinionList.size() > 0) {
			for (AuditOpinionDTO currentOpinion : opinionList) {
				AuditOpinionDTO newOpinion = new AuditOpinionDTO();
				BeanUtils.copyProperties(currentOpinion, newOpinion);
				newOpinion.setProblemNo(newProblemNo);
				newOpinion.setIsDeleted(AuditConstants.isDeleted);
				if (currentOpinion.getOpinionType().equals(
						AuditConstants.opinionType_2)) {
					newOpinion.setAppointFirst(userACode);
					newOpinion.setAppointSecond(userBCode);
				}
				this.auditOpinionDao.addOpinion(newOpinion);

				// 删除意见
				currentOpinion.setIsDeleted(AuditConstants.isDeleted_1);
				this.auditOpinionDao.updateAuditOpinionDTOInfo(currentOpinion);

			}
		}

		if (dealAUsername.equals(userACode)
				&& !(dealBUsername.equals(userBCode))) {

			// 重新生成一个新事件
			copyObject.setRollbackFlag(AuditConstants.rollBackFlag_1);
			this.auditSurveyReviewDao.saveAuditProblemsDTO(copyObject);

			// 说明初审岗位一样了，则需要将该岗位的调查初审意见拷贝到新的事件意见中，并且将老的虚拟删除掉
			paramterOpinion.setOpinionType("'" + AuditConstants.opinionType_3
					+ "','" + AuditConstants.opinionType_4 + "'");
			paramterOpinion.setDealUserName(dealAUsername);

			List<AuditOpinionDTO> dealAUserOpinionList = this.auditOpinionDao
					.queryAuditOpinionDTOInfo(paramterOpinion);

			if (dealAUserOpinionList != null && dealAUserOpinionList.size() > 0) {

				for (AuditOpinionDTO dealAUserOpinion : dealAUserOpinionList) {

					if (dealAUserOpinion.getOpinionType().equals(
							AuditConstants.opinionType_3)) {

						AuditOpinionDTO newOpinion = new AuditOpinionDTO();
						BeanUtils.copyProperties(dealAUserOpinion, newOpinion);
						newOpinion.setProblemNo(newProblemNo);
						newOpinion.setIsDeleted(AuditConstants.isDeleted);
						this.auditOpinionDao.addOpinion(newOpinion);
					}
					// 删除意见
					dealAUserOpinion.setIsDeleted(AuditConstants.isDeleted_1);
					this.auditOpinionDao
							.updateAuditOpinionDTOInfo(dealAUserOpinion);

				}

			}

		} else if (dealBUsername.equals(userBCode)
				&& !(dealAUsername.equals(userACode))) {

			// 重新生成一个新事件
			copyObject.setRollbackFlag(AuditConstants.rollBackFlag_1);
			this.auditSurveyReviewDao.saveAuditProblemsDTO(copyObject);

			// 调查结论复核岗位重新分配给了同一人，则需要将该人之前的意见类型是(调查结论复核)虚拟删除掉然后,拷贝给新的事件中

			paramterOpinion.setOpinionType("'" + AuditConstants.opinionType_3
					+ "','" + AuditConstants.opinionType_4 + "'");
			paramterOpinion.setDealUserName(dealBUsername);

			List<AuditOpinionDTO> dealBUserOpinionList = this.auditOpinionDao
					.queryAuditOpinionDTOInfo(paramterOpinion);

			if (dealBUserOpinionList != null && dealBUserOpinionList.size() > 0) {

				for (AuditOpinionDTO dealBUserOpinion : dealBUserOpinionList) {

					if (dealBUserOpinion.getOpinionType().equals(
							AuditConstants.opinionType_4)) {

						AuditOpinionDTO newOpinion = new AuditOpinionDTO();
						BeanUtils.copyProperties(dealBUserOpinion, newOpinion);
						newOpinion.setProblemNo(newProblemNo);
						newOpinion.setIsDeleted(AuditConstants.isDeleted);
						this.auditOpinionDao.addOpinion(newOpinion);

					}

					// 删除意见
					dealBUserOpinion.setIsDeleted(AuditConstants.isDeleted_1);
					this.auditOpinionDao
							.updateAuditOpinionDTOInfo(dealBUserOpinion);

				}

			}
		} else {

			// 重新生成一个新事件
			copyObject.setRollbackFlag(AuditConstants.rollBackFlag_0);
			copyObject.setTempFlag(AuditConstants.TEMP_FLAG_0);
			this.auditSurveyReviewDao.saveAuditProblemsDTO(copyObject);

			// 将调查审核和复合的意见都删除掉
			paramterOpinion.setOpinionType("'" + AuditConstants.opinionType_3
					+ "','" + AuditConstants.opinionType_4 + "'");
			paramterOpinion.setDealUserName(dealBUsername);

			List<AuditOpinionDTO> OpinionList = this.auditOpinionDao
					.queryAuditOpinionDTOInfo(paramterOpinion);

			if (OpinionList != null && OpinionList.size() > 0) {

				for (AuditOpinionDTO dealOpinion : OpinionList) {
					// 删除意见
					dealOpinion.setIsDeleted(AuditConstants.isDeleted_1);
					this.auditOpinionDao.updateAuditOpinionDTOInfo(dealOpinion);

				}

			}

		}

		// 开启流程

		HcpmsWorkFlowVO wfvo = new HcpmsWorkFlowVO();

		Map<String, String> condition = new HashMap<String, String>();
		condition.put(AuditConstants.AUDIT_BEGIN_TYPE,
				AuditConstants.AUDIT_BEGIN_TYPE_03);
		List<Authority> authorityList = user.getAuthorities();
		List<String> role = new ArrayList<String>();
		for (Authority authority : authorityList) {
			role.add(authority.getAuthority());
		}
		wfvo.setRole(role);
		wfvo.setTaskNo(newProblemNo);
		wfvo.setTaskType(AuditConstants.TASK_TYPE_PROBLEM);
		wfvo.setActCurrent(user.getUsername());
		wfvo.setParamValue(condition);
		wfvo.setAssigner(userACode);

		this.auditWorkFlowService.startWorkFlow(wfvo);

		return newProblemNo;

	}

	/**
	 * 判断当前的意见是否存在，如果存在了就更新，否则保存
	 * 
	 * @param opinion
	 */
	@Transactional
	private void processOpinionInfo(AuditOpinionDTO opinion) {
		List<AuditOpinionDTO> opinionList = this.auditOpinionDao
				.queryAuditOpinionDTOInfo(opinion);
		if (opinionList != null && opinionList.size() > 0) {
			this.auditOpinionDao.updateAuditOpinionDTOInfo(opinion);
		} else {
			this.auditOpinionDao.addOpinion(opinion);
		}

	}

	/**
	 * 审核岗位 审核调查结果 不通过 处理逻辑 此种情况 A 不需要稽核 B 同意 C 同意 流程结束 事件状态关闭 保存审核意见到意见表中
	 * 
	 * @param vo
	 */
	@Transactional
	public Map<String, Object> auditSurveyResultDisagree(
			AuditDispatchUserRequestDTO requestBean, JSONObject transferJson,
			UserDetails user, Map<String, Object> map) throws Exception {
		this.integrityMedicalService.addIntegrityPointTemps(transferJson,
				user.getUsername());
		this.caseCommonService.deleteAuditCasePoint(requestBean.getProblemNo(),
				user.getUsername());

		String problemNo = requestBean.getProblemNo(); // 事件编码
		String checkOpinion = requestBean.getOpinion();// 审核意见

		String CuserOpinionDesc = requestBean.getOpinionDesc(); // C 岗位意见说明
		String CopertionUsername = requestBean.getOpertionUsername(); // c 岗位操作人

		// 更新初审意见和复核意见
		this.updateOpinionInfo(requestBean.getSurveyOpinonDesc(),
				requestBean.getReviewOpinionDesc(), requestBean.getProblemNo());

		// 保存C 岗位意见 1-终止 2-转预警
		Date dealDate = new Date();
		String dealDateStr = GetFormDateUtil.getStrFromDate(dealDate);
		AuditOpinionDTO opionionBean = new AuditOpinionDTO();
		opionionBean.setCreatedBy(CopertionUsername);
		opionionBean.setOpinionType(AuditConstants.opinionType_5);
		opionionBean.setProblemNo(problemNo);
		opionionBean.setTaskType(AuditConstants.taskType_01);
		opionionBean.setOpinion(checkOpinion);// 之前：AuditConstants.opinionResult_1
		opionionBean.setDealUserName(CopertionUsername);
		opionionBean.setDealDate(dealDateStr);
		opionionBean.setOpinionDesc(CuserOpinionDesc);
		opionionBean.setIsDeleted(AuditConstants.isDeleted);
		this.processOpinionInfo(opionionBean);

		// 更新当前事件状态 为已经结束
		AuditProblemsDTO problemBean = new AuditProblemsDTO();
		problemBean.setProblemCode(problemNo);
		problemBean.setProblemStatus(AuditConstants.problemStatus_7);
		problemBean.setUpdatedBy(CopertionUsername);
		problemBean.setTempFlag(AuditConstants.TEMP_FLAG_0);
		this.auditDispatchDao.updateAuditProblemBean(problemBean);

		// 结束当前流程
		Map<String, String> condition = new HashMap<String, String>();
		condition.put(AuditConstants.AUDIT_PROBLEM_CHECK_TYPE,
				AuditConstants.AUDIT_PROBLEM_CHECK_TYPE_01);
		this.auditWorkFlowService.processWorkFlow(problemNo, user, condition,
				AuditConstants.TASK_TYPE_PROBLEM);

		// 对于转预警的，需要向temp表中写数据
		if (AuditConstants.opinionResult_3.equals(checkOpinion)) {
			auditService.saveProblemTemp(problemNo);
			warningFromAuditService.notice();
		}

		map.put("state", AuditConstants.FLAG_TURE);
		map.put("msg", AuditConstants.OPERATE_SUCCESS);
		return map;
	}

	@Transactional
	private void updateOpinionInfo(String surveyOpinionDesc,
			String reviewOpinionDesc, String problemNo) {

		AuditOpinionDTO opinion = new AuditOpinionDTO();
		opinion.setProblemNo(problemNo);
		opinion.setTaskType(AuditConstants.taskType_01);
		opinion.setOpinionType(AuditConstants.opinionType_3);
		opinion.setOpinionDesc(surveyOpinionDesc);

		this.auditOpinionDao.updateAuditOpinionDTOInfo(opinion);

		opinion.setOpinionType(AuditConstants.opinionType_4);
		opinion.setOpinionDesc(reviewOpinionDesc);

		this.auditOpinionDao.updateAuditOpinionDTOInfo(opinion);
	}

	/**
	 * 处理暂存事件
	 */
	@Transactional
	@Override
	public AuditDispatchUserResponseDTO processTempSave(
			AuditDispatchUserRequestDTO requestBean, String type,
			JSONObject transferJson, String userName) throws Exception {
		AuditDispatchUserResponseDTO responseBean = new AuditDispatchUserResponseDTO();
		// 暂存调查审核
		if (type_save.equals(type)) {
			HcpmsStorageDTO tempObject = this.setTempObject(requestBean,
					userName, AuditConstants.opinionType_5,
					AuditConstants.examine, AuditConstants.sjModule);
			this.hcpmsStorageService.saveStorageData(tempObject, false);
			// 扣分
			this.caseCommonService.saveAuditCasePoint(
					requestBean.getProblemNo(), transferJson, userName);

		} else if (type_load.equals(type)) {
			HcpmsStorageDTO tempObject = this.setTempObject(requestBean,
					userName, AuditConstants.opinionType_5,
					AuditConstants.examine, AuditConstants.sjModule);

			Object obj = this.hcpmsStorageService.getStorageDataMap(tempObject);
			if (obj != null) {

				AuditDispatchUserRequestDTO currentObj = JSONObject
						.toJavaObject(((JSONObject) obj),
								AuditDispatchUserRequestDTO.class);
				AuditOpinionDTO loadOpinion = new AuditOpinionDTO();
				loadOpinion.setOpinion(currentObj.getOpinion());
				loadOpinion.setOpinionDesc(currentObj.getOpinionDesc());
				responseBean.setAuditOpinion(loadOpinion);

			}

		}
		return responseBean;

	}

	/**
	 * 调查审核，批量提交
	 */
	@Transactional
	@Override
	public Map<String, Object> researchCheckBatchSubmit(
			String[] problemCodeList, UserDetails user, String opinion,
			String opinionDesc) throws Exception {
		Map<String, Object> result = new HashMap<String, Object>();
		result.put("state", AuditConstants.FLAG_FALSE);
		result.put("msg", AuditConstants.OPERATE_SUCCESS);
		if (problemCodeList == null || problemCodeList.length == 0
				|| !StringUtils.hasText(opinion)) {
			result.put("state", AuditConstants.FLAG_FALSE);
			result.put("msg", AuditConstants.OPERATE_SUCCESS);
			return result;
		}
		// 默认提示语
		result.put("msg", AuditConstants.OPERATE_SUCCESS + "成功0条，失败"
				+ problemCodeList.length + "条！");
		// 可选择“重新调查”操作的事件
		List<AuditDispatchUserRequestDTO> againList = new ArrayList<AuditDispatchUserRequestDTO>();
		// 可选择“同意稽核”操作的事件
		List<AuditDispatchUserRequestDTO> auditList = new ArrayList<AuditDispatchUserRequestDTO>();
		// 可选择“同意调查终止”操作的事件
		List<AuditDispatchUserRequestDTO> stopList = new ArrayList<AuditDispatchUserRequestDTO>();
		// 可选择“违规证据不足，提请预警跟踪处理”操作的事件
		List<AuditDispatchUserRequestDTO> warnList = new ArrayList<AuditDispatchUserRequestDTO>();

		// 过程中剔除的失败列表
		// List<String> failList = new ArrayList<String>();

		// 第一步，各案件允许的处理方式归类
		for (String problemCode : problemCodeList) {
			// 逐个查询出每个事件的调查意见、复核意见进行归类。
			AuditOpinionDTO reviewOpinion = this.getOpinionByOpinonType(
					problemCode, AuditConstants.opinionType_4);// 复核意见
			AuditOpinionDTO researchOpinion = this.getOpinionByOpinonType(
					problemCode, AuditConstants.opinionType_3);// 调查意见(结论)
			if (reviewOpinion == null || reviewOpinion.getOpinion() == null) {
				// failList.add(problemCode);
				continue;
			}
			AuditDispatchUserRequestDTO vo = new AuditDispatchUserRequestDTO();
			vo.setSurveyOpinonDesc(researchOpinion.getOpinion());
			vo.setReviewOpinionDesc(reviewOpinion.getOpinion());
			vo.setProblemNo(problemCode);
			vo.setUser(user);
			vo.setOpertionUsername(user.getUsername());
			vo.setOpinion(opinion);
			vo.setOpinionDesc(opinionDesc);

			if (AuditConstants.opinionResult_0.equals(reviewOpinion
					.getOpinion())) {// 复核意见为保留意见，归为重新调查
				againList.add(vo);
			} else if (AuditConstants.opinionResult_1.equals(reviewOpinion
					.getOpinion())) {// 复核意见为同意的，需要通过调查结论再进行细化划分
				if (researchOpinion == null
						|| researchOpinion.getOpinion() == null) {
					// failList.add(problemCode);
					continue;
				}
				if (AuditConstants.opinionResult_1.equals(researchOpinion
						.getOpinion())) {// 调查结论为“需要稽核”，结论：“同意稽核”或“重新调查”
					againList.add(vo);
					auditList.add(vo);
				} else if (AuditConstants.opinionResult_0
						.equals(researchOpinion.getOpinion())) {// 调查结论为“无需稽核”，结论：“重新调查”、“同意调查终止”或“转预警”
					againList.add(vo);
					stopList.add(vo);
					warnList.add(vo);
				}
			}
		}

		// 第二步，分别处理4种批量意见
		if (AuditConstants.opinionResult_0.equals(opinion)) {// 重新调查
			if (againList != null && againList.size() > 0) {
				int successNum = 0;
				for (AuditDispatchUserRequestDTO vo : againList) {
					AuditOpinionDTO problemCheckOpinion = this
							.getOpinionByOpinonType(vo.getProblemNo(),
									AuditConstants.opinionType_2);// 事件审核意见，找出上一次的分配人员
					vo.setUserCode(problemCheckOpinion.getAppointFirst());
					vo.setUserBCode(problemCheckOpinion.getAppointSecond());
					JSONObject transferJson = this.caseCommonService
							.queryBatchOpertionAuditCasePoint(
									vo.getProblemNo(), user.getUsername());

					if (judgeProblemStatus(vo.getProblemNo(),
							AuditConstants.problemStatus_6)) {
						// failList.add(vo.getProblemNo());
						continue;
					}
					try {
						this.auditSurveyResultTask(vo, user, transferJson);
					} catch (Exception e) {// 如果抛出异常，表示这一条操作失败。
						e.printStackTrace();
						// failList.add(vo.getProblemNo());
						continue;
					}
					successNum++;
				}
				result.put("state", AuditConstants.FLAG_TURE);
				result.put("msg", AuditConstants.OPERATE_SUCCESS + "成功"
						+ successNum + "条，失败"
						+ (problemCodeList.length - successNum) + "条！");
			}

		} else if (AuditConstants.opinionResult_1.equals(opinion)) {// 同意稽核
			if (auditList != null && auditList.size() > 0) {
				int successNum = 0;
				for (AuditDispatchUserRequestDTO vo : auditList) {
					AuditOpinionDTO problemCheckOpinion = this
							.getOpinionByOpinonType(vo.getProblemNo(),
									AuditConstants.opinionType_2);// 事件审核意见，找出上一次的分配人员
					vo.setUserCode(problemCheckOpinion.getAppointFirst());
					vo.setUserBCode(problemCheckOpinion.getAppointSecond());
					JSONObject transferJson = this.caseCommonService
							.queryBatchOpertionAuditCasePoint(
									vo.getProblemNo(), user.getUsername());
					if (judgeProblemStatus(vo.getProblemNo(),
							AuditConstants.problemStatus_6)) {
						// failList.add(vo.getProblemNo());
						continue;
					}
					try {
						this.auditSurveyResultTask(vo, user, transferJson);
					} catch (Exception e) {
						e.printStackTrace();
						// failList.add(vo.getProblemNo());
						continue;
					}
					successNum++;
				}
				result.put("state", AuditConstants.FLAG_TURE);
				result.put("msg", AuditConstants.OPERATE_SUCCESS + "成功"
						+ successNum + "条，失败"
						+ (problemCodeList.length - successNum) + "条！");
			}

		} else if (AuditConstants.opinionResult_2.equals(opinion)) {// 同意调查终止
			if (againList != null && againList.size() > 0) {
				int successNum = 0;
				for (AuditDispatchUserRequestDTO vo : stopList) {
					Map<String, Object> resultMap = new HashMap<String, Object>();
					JSONObject transferJson = this.caseCommonService
							.queryBatchOpertionAuditCasePoint(
									vo.getProblemNo(), user.getUsername());
					if (judgeProblemStatus(vo.getProblemNo(),
							AuditConstants.problemStatus_6)) {
						// failList.add(vo.getProblemNo());
						continue;
					}
					try {
						this.auditSurveyResultDisagree(vo, transferJson, user,
								resultMap);
					} catch (Exception e) {
						e.printStackTrace();
						// failList.add(vo.getProblemNo());
						continue;
					}
					successNum++;
				}
				result.put("state", AuditConstants.FLAG_TURE);
				result.put("msg", AuditConstants.OPERATE_SUCCESS + "成功"
						+ successNum + "条，失败"
						+ (problemCodeList.length - successNum) + "条！");
			}

		} else if (AuditConstants.opinionResult_3.equals(opinion)) {// 违规证据不足，提请预警跟踪处理
			if (warnList != null && warnList.size() > 0) {
				int successNum = 0;
				for (AuditDispatchUserRequestDTO vo : warnList) {
					Map<String, Object> resultMap = new HashMap<String, Object>();
					JSONObject transferJson = this.caseCommonService
							.queryBatchOpertionAuditCasePoint(
									vo.getProblemNo(), user.getUsername());
					if (judgeProblemStatus(vo.getProblemNo(),
							AuditConstants.problemStatus_6)) {
						// failList.add(vo.getProblemNo());
						continue;
					}
					try {
						this.auditSurveyResultDisagree(vo, transferJson, user,
								resultMap);
					} catch (Exception e) {
						e.printStackTrace();
						// failList.add(vo.getProblemNo());
						continue;
					}
					successNum++;
				}
				result.put("state", AuditConstants.FLAG_TURE);
				result.put("msg", AuditConstants.OPERATE_SUCCESS + "成功"
						+ successNum + "条，失败"
						+ (problemCodeList.length - successNum) + "条！");
			}

		}
		return result;

		// 以上代码重构一下，测试一下
	}

	/**
	 * 根据案件编码加载该案件的复核的意见信息
	 * 
	 * @param caseCode
	 */
	private AuditOpinionDTO getOpinionByOpinonType(String problemCode,
			String opinionType) {
		AuditOpinionDTO parameter = new AuditOpinionDTO();
		parameter.setProblemNo(problemCode);
		parameter.setTaskType(AuditConstants.taskType_01);

		// B岗位稽核结论复核原始意见
		parameter.setOpinionType(opinionType);
		AuditOpinionDTO surveyOpinonB = this.auditOpinionDao
				.queryOpionionDTO(parameter);
		return surveyOpinonB;
	}

	private boolean judgeProblemStatus(String code, String judgeStatus) {
		// 判断当前问题是否处于调查待审核状态，如果不是，表示出现并发问题，已经被别人操作过了，此条需要返回操作失败
		AuditProblemsDTO paramter = new AuditProblemsDTO();
		paramter.setProblemCode(code);
		AuditProblemsDTO problemBean = this.auditSurveyReviewDao
				.queryAuditProblemsDTO(paramter);
		if (judgeStatus.equals(problemBean.getProblemStatus())) {
			return false;
		}
		return true;
	}

}
